﻿// =====================================================
// Copyright (C) 2016-2020 Fanjia
// All rights reserved
// 机器名称: PC-LIWEI
// 创建时间: 2020/2/12 19:41:40
// 创 建 人: 李伟
// ======================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

namespace WindowsFormsApplication1.RSA
{
    /// <summary>
    /// 
    /// </summary>
    public class RSAHelper
    {
        private string PrivateKeyFilePath = AppDomain.CurrentDomain.BaseDirectory + @"RSA\private.key";
        private string PrivateKeyPasswd = "";
        private string PublicKeyFilePath = AppDomain.CurrentDomain.BaseDirectory + @"RSA\luobo.cer";
        private int MAX_ENCRYPT_BLOCK = 245;
        private int MAX_DECYPT_BLOCK = 256;

        public string GetEncryptedMsg(string encryStr)
        {
            byte[] encryptedData;
            using (var rsa = GetPublicKey(PublicKeyFilePath))
            {
                var plainData = Encoding.UTF8.GetBytes(encryStr);
                using (var plaiStream = new MemoryStream(plainData))
                {
                    using (var crypStream = new MemoryStream())
                    {
                        var offSet = 0;
                        var inputLen = plainData.Length;
                        for (var i = 0; inputLen - offSet > 0; offSet = i * MAX_ENCRYPT_BLOCK)
                        {
                            if (inputLen - offSet > MAX_ENCRYPT_BLOCK)
                            {
                                var buffer = new Byte[MAX_ENCRYPT_BLOCK];
                                plaiStream.Read(buffer, 0, MAX_ENCRYPT_BLOCK);
                                var cryptograph = rsa.Encrypt(buffer, false);
                                crypStream.Write(cryptograph, 0, cryptograph.Length);
                            }
                            else
                            {
                                var buffer = new Byte[inputLen - offSet];
                                plaiStream.Read(buffer, 0, inputLen - offSet);
                                var cryptograph = rsa.Encrypt(buffer, false);
                                crypStream.Write(cryptograph, 0, cryptograph.Length);
                            }
                            ++i;
                        }
                        crypStream.Position = 0;
                        encryptedData = crypStream.GetBuffer();
                    }
                }
            }
            return System.Convert.ToBase64String(encryptedData);
            //return BitConverter.ToString(encryptedData).Replace("-", string.Empty);
        }

        public string GetEncryptedMsg1(string encryStr)
        {
            byte[] encryptedData;
            using (var rsa = GetPublicKey(PublicKeyFilePath))
            {
                var plainData = Encoding.UTF8.GetBytes(encryStr);
                //var cryptograph = rsa.Encrypt(plainData, false);
                //return BitConverter.ToString(cryptograph).Replace("-", string.Empty);

                using (var plaiStream = new MemoryStream(plainData))
                {
                    using (var crypStream = new MemoryStream())
                    {
                        var offSet = 0;
                        var inputLen = plainData.Length;
                        for (var i = 0; inputLen - offSet > 0; offSet = i * MAX_ENCRYPT_BLOCK)
                        {
                            if (inputLen - offSet > MAX_ENCRYPT_BLOCK)
                            {
                                var buffer = new Byte[MAX_ENCRYPT_BLOCK];
                                plaiStream.Read(buffer, 0, MAX_ENCRYPT_BLOCK);
                                var cryptograph = rsa.Encrypt(buffer, false);
                                crypStream.Write(cryptograph, 0, cryptograph.Length);
                            }
                            else
                            {
                                var buffer = new Byte[inputLen - offSet];
                                plaiStream.Read(buffer, 0, inputLen - offSet);
                                var cryptograph = rsa.Encrypt(buffer, false);
                                crypStream.Write(cryptograph, 0, cryptograph.Length);
                            }
                            ++i;
                        }
                        crypStream.Position = 0;
                        encryptedData = crypStream.GetBuffer();
                    }
                }
            }
            return System.Convert.ToBase64String(encryptedData);
            return BitConverter.ToString(encryptedData).Replace("-", string.Empty);
        }

        internal byte[] GetDecryptedMsg(byte[] encryptedBytes)
        {
            using (var rsa = GetPrivateKey(PrivateKeyFilePath, PrivateKeyPasswd))
            {
                byte[] decryptedData;
                using (var plaiStream = new MemoryStream(encryptedBytes))
                {
                    using (var decrypStream = new MemoryStream())
                    {
                        var offSet = 0;
                        var inputLen = encryptedBytes.Length;
                        for (var i = 0; inputLen - offSet > 0; offSet = i * MAX_DECYPT_BLOCK)
                        {
                            if (inputLen - offSet > MAX_DECYPT_BLOCK)
                            {
                                var buffer = new Byte[MAX_DECYPT_BLOCK];
                                plaiStream.Read(buffer, 0, MAX_DECYPT_BLOCK);
                                var decrypData = rsa.Decrypt(buffer, false);
                                decrypStream.Write(decrypData, 0, decrypData.Length);
                            }
                            else
                            {
                                var buffer = new Byte[inputLen - offSet];
                                plaiStream.Read(buffer, 0, inputLen - offSet);
                                var decrypData = rsa.Decrypt(buffer, false);
                                decrypStream.Write(decrypData, 0, decrypData.Length);
                            }
                            ++i;
                        }
                        decrypStream.Position = 0;
                        decryptedData = decrypStream.GetBuffer();
                    }
                }
                return decryptedData;
            }
        }

        internal byte[] GetDecryptedMsg1(byte[] encryptedBytes)
        {
            using (var rsa = GetPrivateKey(PrivateKeyFilePath, PrivateKeyPasswd))
            {
                byte[] output = rsa.Decrypt(encryptedBytes, false);
                return output;


                byte[] decryptedData;
                using (var plaiStream = new MemoryStream(encryptedBytes))
                {
                    using (var decrypStream = new MemoryStream())
                    {
                        var offSet = 0;
                        var inputLen = encryptedBytes.Length;
                        for (var i = 0; inputLen - offSet > 0; offSet = i * MAX_DECYPT_BLOCK)
                        {
                            if (inputLen - offSet > MAX_DECYPT_BLOCK)
                            {
                                var buffer = new Byte[MAX_DECYPT_BLOCK];
                                plaiStream.Read(buffer, 0, MAX_DECYPT_BLOCK);
                                var decrypData = rsa.Decrypt(buffer, false);
                                decrypStream.Write(decrypData, 0, decrypData.Length);
                            }
                            else
                            {
                                var buffer = new Byte[inputLen - offSet];
                                plaiStream.Read(buffer, 0, inputLen - offSet);
                                var decrypData = rsa.Decrypt(buffer, false);
                                decrypStream.Write(decrypData, 0, decrypData.Length);
                            }
                            ++i;
                        }
                        decrypStream.Position = 0;
                        decryptedData = decrypStream.GetBuffer();
                    }
                }
                return decryptedData;
            }
        }

        private RSACryptoServiceProvider GetPrivateKey(string priKeyFile, string keyPwd)
        {
            //var pc = new X509Certificate2(priKeyFile, keyPwd, X509KeyStorageFlags.MachineKeySet);
            //return (RSACryptoServiceProvider)pc.PrivateKey;

            var priKey = @"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDNwKRWqu85Zd3JKPfGkTO7pfptooebD8t6Pikq2LHjv1X3C0xgjpgUH8cyYkK+dan80pY67+rcrf8YOI5ZbUtkthawjJvd6CdOPdXznmrB6Tq3BjR5p6tKx1AKlM/QSU8XAVavSXArFA6pW+pt5attPIXIPdAzWvmtMKV8evamRys+YIjxRaJH6ckWZ9pckLcbEjt2MTLRGRkFhqn7mmJDH+E1cnxTh5ggwPwAlXL+/rfDKwkFLAtuFJudJ1gylHYckgljJw8R1LMF/qNGExqcl5YPJ8LaMvNglt7Gx+28GvHXYfKy+3erdQI5v0jkpiq/K8dcAVYQTyi9nRSffUubAgMBAAECggEBALt0oQVpNQ0JVxiYH66kygpTvSa35m6K5GraSW2FAgWqZCrw+0QZhksHbNflmEOoNhhm0IKf5U3rpLcvh9nH7uGx2Fg/sx5pDa6GPfB4S3GiCWGI4LRZ44D8uFr7m557u/gMuyp2cSB+ZKE+YgaAMkAS3RxD3PV9FG8LHCqeaSuxlpkGHOxMRwqj6iBVj2IcSkCWVTOJVMPbNFdR9IrJoSoIk977sT9nwRGa17Ipa7tN+9aWabasbAzePqwxWOmhtK8sjS7Q4ZrHbZnACEVpam0TuX3BO4Wszh6oDlA7ty6A4JXV0Lf424vaOjJO2o/4aQs0UXSGyzY52JWOEJKA1ekCgYEA9GXYXk0W2thfMSg3LBOxzPvEowZUK7brZBUrW17RUCGRrDMmmJelQnHszdEZcxyFndkyNb6a4iQ5TO+Yhr6K4e1AO4J7I/dvnFsFUCWs5aoF14BGvDgAlfYEXNCcJD4+DxduV1SWrCcKHnq0+Z40NHLKq883rFVymKXQEYLQfG0CgYEA14UkW+cKYIYt6q6AU20bAYuSZJkL5IcB3d1f83QcC9fCxZEfSUCDLlkk8ShiQytBAOPPUBQ4A2c7q4RKfiTKJP6NjpjwEe6K5v6s4RLrukXIs/C4VRpj19R0ZZ7IrSV0hAUEPoHs/P3Tl+/22o3ZQWutHf+umyByy9qq3KsPUycCgYAectXbIdWYHF73u9/r0ORU+oUMHoy8CYUYKf8F2jFPv27ruk+zsSj4t0LefY+jJMmM2fOEeKPJSuQMrskc+H5LGYjoISCAYaJ5I2ntC1SYJG+n4qZtari/9i+i9KaPaWXH8Y5guPwwpIiBNZ54fvpYEnknoKB6CwdE91uN4vNgnQKBgDze3+wND0M/4owcCSaG9E+1af17tH4xG3fcZJNQQfOeVuaSHHIGBIb8qpBqRYaPGubzcMQ/Uaq0Z4gD7z49idJ1Cuoxi+ykoRqo548SVv3fY9ZesNFoiLaWzOE+vZMZtxTqjc5Rx+uUjUSmg+QqmCgAD38fjeNGgOXOtt9oeQWVAoGBAODVpMrxiPWyQglaAHwGo1HjOBxtRA0pZxdud8pRSl1TckCOpHm3iWJNLbOU3unjeKX8qE4PX0e5AZ65zfoqGOaPBLbALUnwZ+BxENlm6HH5Cm4eXf2oOaSEgLa5fNiEJzFoYirO2MKkJLwDUOSB8cw8DrzO3qTe1FGQwu+tQvL7";
            ////var priKey = @"+m5thEBVJg27O8uUp95O88McR17mFw9UVQ5w3Zn9ChK93GzmB1ltob3Sm847YW18KyoxDbqbh6MlRy6yt5v/MDpbbs5lEcwME9YmgGVvayfWDMquFqHnX05pEoE05uvAyDj1UtT7ZlMn6TmOzTLpfoGnkADoyB3LraAa6qGkNWa9/fmV3xU11LH141fidO9iG5L5Gx5xw/JEIxTAblXbxqxsWeCBbkNpW4TqtbX5CH1EdhWYxOL060Ujkr1Qe5Zp0TntaKK2lY4RswKQIDAQABAoIBAH2p/zE5OEGsrTsn4kPDMiAUTm8NIY/H60m8w20oK+ixasX0tJD3bxWjSL1p5BBub4WjMnLNgiPJqAkPtK10YPUb5QzYFpEXQwEh3Uj08dKc48GPYHYE/RZdJEI3vRBPshVvAVN2OpCm23usCXPiMz+qBJte7nF80MEC+YlgYW9M1xDYseAHCfpbF38KIUrI235YN5G72MhFBQc8SrJpOp4qvHWR2yQ25ryUeqOMqqfJchMbP3r49mxU+wXUNicuRfEvFVbvwGG5NiurizD4Ts/+lR5EFJUUaF9qJzKl9BifiwVS6Cgwi9Pl4Em9Y4YUok9Wncw7xC3WTZX8sbqdUQECgYEA7iLieUJl8ngHd8tGjmHdTmlZBJftiSsKcS0S6iMbcVlR/oBT09sV3aJFGcVQZGCOwlTNCUUUJ0nc8r/aR0daODBYQLuEkY2pBZ5K1OqPZ6H8CRsyEl1E0CLA4CGRH8l3Ua/otFdxgnSuTzla5TK4uCTyO0NwXyj/vFL6CMsGFBUCgYEAz1IytWOw11ATSxUeIjJYgCGLMzeq20pP1avi9y7ri1QAudKIRWqJh/oq4FJ01EWYmsV6aQadAB61zNOvKRY9E6fYCFeMziJIciFKUvBNNsRWy5bkM58Q+z3BZv2hqncU8G5ZYcK0wWvPlVwFYMx8RveVdkFUsw9Wfu3DMXH5zMUCgYBY6/3Vec3HtLpVKTq3gCO7W+s5o+G3DrNff41IkMN2l/veJN0ohu6rTCSxctSKJuQn/LJze7AC27n9i1Zet24g/Sx3P45JK7SpvGoFB3F1KS+L1vPjl6BSeCe9ics/K2O6xQ0ICn8AT8GnI6ulWkNPv7wUFSKo5g5YrENhdS5X4QKBgFzprrYiLm/ggDUHCtEylP0fi13x1c2feTX+aaJz0bZIeGbPFqldfLOHB04vRhKX+jNqy1hkUVpraPiZ6gdU4xx6/VOHwR/kt2kGyGNxNHmV9nwZbL5BzH98hr+cbaaS5bx3B/HLK+z/XzHF4tcl7ZB0hvRPhSEWf6I09mSjetstAoGBAL169VzKB3jdchzGUSHqoo21kpad1zSKWzVYyu9gmtFg4O51RHCKbo7k6/dt30UnSUQ75icUlJfO0ZdKPqUnJHUUEGfkuMihXRPtf0h9mEiUSO3CLNbMsr4qzcIcfpfAlYCw/e0eLrY98LTDC152KXeFzNJHFwRiDYcIoV5GjGSR";
            //return DecodeRSAPrivateKey(priKey);

            var priKeyStr = RSAPrivateKeyJava2DotNet(priKey);

            RSACryptoServiceProvider rsaService = new RSACryptoServiceProvider();
            rsaService.FromXmlString(priKeyStr);
            return rsaService;
        }

        private RSACryptoServiceProvider GetPublicKey(string pubKeyFile)
        {
            //var pc = new X509Certificate2(pubKeyFile);
            //return (RSACryptoServiceProvider)pc.PublicKey.Key;

            //string pemPublicCert = Path.Combine(Application.StartupPath, "CCQTGBtest.pem");
            /*using (FileStream fs = new FileStream(pemPublicCert, FileMode.Open, FileAccess.Read))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    base64X509Cert = sr.ReadToEnd().Trim();
                }
            }*/

            //var base64X509Cert = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcCkVqrvOWXdySj3xpEzu6X6baKHmw/Lej4pKtix479V9wtMYI6YFB/HMmJCvnWp/NKWOu/q3K3/GDiOWW1LZLYWsIyb3egnTj3V855qwek6twY0eaerSsdQCpTP0ElPFwFWr0lwKxQOqVvqbeWrbTyFyD3QM1r5rTClfHr2pkcrPmCI8UWiR+nJFmfaXJC3GxI7djEy0RkZBYap+5piQx/hNXJ8U4eYIMD8AJVy/v63wysJBSwLbhSbnSdYMpR2HJIJYycPEdSzBf6jRhManJeWDyfC2jLzYJbexsftvBrx12Hysvt3q3UCOb9I5KYqvyvHXAFWEE8ovZ0Un31LmwIDAQAB";
            var base64X509Cert = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyB34GZ/fgkromEFq6p55wqq4GMtMt/EnvVvauVUYiS4A7LCuntdHKE/aFKZBLNdCgRyKiiZ5rV3coZrqfZ40R6078kOugIQ/kQjB0zhrH9EkmbptyXOAdfAsNstj9NAqZDjcSJh3J65+x1l5hffDXMOFts3W8G2RDuS4ThzPz+v9RbFCUT6reQCZfNMH+gsGWYaFF5V+9eq2GwIyjhTLBfQyCANj/sQE10PHA3lRt3JH8s2py7HFukK8qeVPz8vUKEDp7p6mJ2eG75zcTM9OZhJYZc6tJGje0+47tF696DPE7EW+b/pQiMIqwZ9gWRQQZzpwuP1906XACeAYGoRhRwIDAQAB";
            //载入公钥
            //var base64X509Cert = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcCkVqrvOWXdySj3xpEzu6X6baKHmw/Lej4pKtix479V9wtMYI6YFB/HMmJCvnWp/NKWOu/q3K3/GDiOWW1LZLYWsIyb3egnTj3V855qwek6twY0eaerSsdQCpTP0ElPFwFWr0lwKxQOqVvqbeWrbTyFyD3QM1r5rTClfHr2pkcrPmCI8UWiR+nJFmfaXJC3GxI7djEy0RkZBYap+5piQx/hNXJ8U4eYIMD8AJVy/v63wysJBSwLbhSbnSdYMpR2HJIJYycPEdSzBf6jRhManJeWDyfC2jLzYJbexsftvBrx12Hysvt3q3UCOb9I5KYqvyvHXAFWEE8ovZ0Un31LmwIDAQAB";
            //var derCert = Convert.FromBase64String(base64X509Cert);
            //var x509 = new X509Certificate2(derCert);
            //return (RSACryptoServiceProvider)x509.PublicKey.Key;

            var rsaa = ConvertFromPemPublicKey(base64X509Cert);
            RSACryptoServiceProvider rsab = new RSACryptoServiceProvider();
            rsab.ImportParameters(rsaa);
            return rsab;
        }

        /// <summary>  
        /// 将pem格式公钥(1024 or 2048)转换为RSAParameters  
        /// </summary>  
        /// <param name="pemFileConent">pem公钥内容</param>  
        /// <returns>转换得到的RSAParamenters</returns>  
        public static RSAParameters ConvertFromPemPublicKey(string pemFileConent)
        {
            if (string.IsNullOrEmpty(pemFileConent))
            {
                throw new ArgumentNullException("pemFileConent", "This arg cann't be empty.");
            }
            pemFileConent = pemFileConent.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");
            byte[] keyData = Convert.FromBase64String(pemFileConent);
            bool keySize1024 = (keyData.Length == 162);
            bool keySize2048 = (keyData.Length == 294);
            if (!(keySize1024 || keySize2048))
            {
                throw new ArgumentException("pem file content is incorrect, Only support the key size is 1024 or 2048");
            }
            byte[] pemModulus = (keySize1024 ? new byte[128] : new byte[256]);
            var pemPublicExponent = new byte[3];
            Array.Copy(keyData, (keySize1024 ? 29 : 33), pemModulus, 0, (keySize1024 ? 128 : 256));
            Array.Copy(keyData, (keySize1024 ? 159 : 291), pemPublicExponent, 0, 3);
            var para = new RSAParameters { Modulus = pemModulus, Exponent = pemPublicExponent };
            byte[] sss = para.Modulus;
            
            return para;
        }

        //public RSACryptoServiceProvider DecodeRSAPrivateKey(string priKey)
        //{
        //    var privkey = Convert.FromBase64String(priKey);
        //    byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;

        //    // ---------  Set up stream to decode the asn.1 encoded RSA private key  ------
        //    MemoryStream mem = new MemoryStream(privkey);
        //    BinaryReader binr = new BinaryReader(mem);    //wrap Memory Stream with BinaryReader for easy reading
        //    byte bt = 0;
        //    ushort twobytes = 0;
        //    int elems = 0;
        //    try
        //    {
        //        twobytes = binr.ReadUInt16();
        //        if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
        //            binr.ReadByte();        //advance 1 byte
        //        else if (twobytes == 0x8230)
        //            binr.ReadInt16();       //advance 2 bytes
        //        else
        //            return null;

        //        twobytes = binr.ReadUInt16();
        //        if (twobytes != 0x0102) //version number
        //            return null;
        //        bt = binr.ReadByte();
        //        if (bt != 0x00)
        //            return null;


        //        //------  all private key components are Integer sequences ----
        //        elems = GetIntegerSize(binr);
        //        MODULUS = binr.ReadBytes(elems);

        //        elems = GetIntegerSize(binr);
        //        E = binr.ReadBytes(elems);

        //        elems = GetIntegerSize(binr);
        //        D = binr.ReadBytes(elems);

        //        elems = GetIntegerSize(binr);
        //        P = binr.ReadBytes(elems);

        //        elems = GetIntegerSize(binr);
        //        Q = binr.ReadBytes(elems);

        //        elems = GetIntegerSize(binr);
        //        DP = binr.ReadBytes(elems);

        //        elems = GetIntegerSize(binr);
        //        DQ = binr.ReadBytes(elems);

        //        elems = GetIntegerSize(binr);
        //        IQ = binr.ReadBytes(elems);

        //        // ------- create RSACryptoServiceProvider instance and initialize with public key -----
        //        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        //        RSAParameters RSAparams = new RSAParameters();
        //        RSAparams.Modulus = MODULUS;
        //        RSAparams.Exponent = E;
        //        RSAparams.D = D;
        //        RSAparams.P = P;
        //        RSAparams.Q = Q;
        //        RSAparams.DP = DP;
        //        RSAparams.DQ = DQ;
        //        RSAparams.InverseQ = IQ;
        //        RSA.ImportParameters(RSAparams);
        //        return RSA;
        //    }
        //    catch (Exception ex)
        //    {
        //        return null;
        //    }
        //    finally
        //    {
        //        binr.Close();
        //    }
        //}

        //private int GetIntegerSize(BinaryReader binr)
        //{
        //    byte bt = 0;
        //    byte lowbyte = 0x00;
        //    byte highbyte = 0x00;
        //    int count = 0;
        //    bt = binr.ReadByte();
        //    if (bt != 0x02)        //expect integer
        //        return 0;
        //    bt = binr.ReadByte();

        //    if (bt == 0x81)
        //        count = binr.ReadByte();    // data size in next byte
        //    else
        //    if (bt == 0x82)
        //    {
        //        highbyte = binr.ReadByte();    // data size in next 2 bytes
        //        lowbyte = binr.ReadByte();
        //        byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
        //        count = BitConverter.ToInt32(modint, 0);
        //    }
        //    else
        //    {
        //        count = bt;        // we already have the data size
        //    }

        //    while (binr.ReadByte() == 0x00)
        //    {    //remove high order zeros in data
        //        count -= 1;
        //    }
        //    binr.BaseStream.Seek(-1, SeekOrigin.Current);        //last ReadByte wasn't a removed zero, so back up a byte
        //    return count;
        //}

        //private RSACryptoServiceProvider DecodeRSAPrivateKey(string privateKey)
        //{
        //    var privateKeyBits = System.Convert.FromBase64String(privateKey);

        //    var RSA = new RSACryptoServiceProvider();
        //    var RSAparams = new RSAParameters();

        //    using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
        //    {
        //        byte bt = 0;
        //        ushort twobytes = 0;
        //        twobytes = binr.ReadUInt16();
        //        if (twobytes == 0x8130)
        //            binr.ReadByte();
        //        else if (twobytes == 0x8230)
        //            binr.ReadInt16();
        //        else
        //            throw new Exception("Unexpected value read binr.ReadUInt16()");

        //        twobytes = binr.ReadUInt16();
        //        if (twobytes != 0x0102)
        //            throw new Exception("Unexpected version");

        //        bt = binr.ReadByte();
        //        if (bt != 0x00)
        //            throw new Exception("Unexpected value read binr.ReadByte()");

        //        RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
        //        RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
        //        RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
        //        RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
        //        RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
        //        RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
        //        RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
        //        RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
        //    }

        //    RSA.ImportParameters(RSAparams);
        //    return RSA;
        //}

        //private int GetIntegerSize(BinaryReader binr)
        //{
        //    byte bt = 0;
        //    byte lowbyte = 0x00;
        //    byte highbyte = 0x00;
        //    int count = 0;
        //    bt = binr.ReadByte();
        //    if (bt != 0x02)
        //        return 0;
        //    bt = binr.ReadByte();

        //    if (bt == 0x81)
        //        count = binr.ReadByte();
        //    else
        //        if (bt == 0x82)
        //    {
        //        highbyte = binr.ReadByte();
        //        lowbyte = binr.ReadByte();
        //        byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
        //        count = BitConverter.ToInt32(modint, 0);
        //    }
        //    else
        //    {
        //        count = bt;
        //    }

        //    while (binr.ReadByte() == 0x00)
        //    {
        //        count -= 1;
        //    }
        //    binr.BaseStream.Seek(-1, SeekOrigin.Current);
        //    return count;
        //}

        /***************以下是java提供的公私钥转成.net公私钥XML的方式*************************************/
        /// <summary> 
        /// RSA公钥格式转换，java->.net
        /// </summary>
        /// <param name="publicKey">java生成的公钥</param>
        /// <returns></returns>
        public static string RSAPublicKeyJava2DotNet(string publicKey)
        {
            RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
            return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
                Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
                Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
        }

        /// <summary>
        /// RSA私钥格式转换，java->.net
        /// </summary>
        /// <param name="privateKey">java生成的RSA私钥</param>
        /// <returns></returns>
        public string RSAPrivateKeyJava2DotNet(string privateKey)
        {
            RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));

            return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
                Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));

        }

        private static RSACryptoServiceProvider DecodeRSAPrivateKey(string privateKey, string signType= "RSA2")
        {
            var privkey = Convert.FromBase64String(privateKey);
            byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;

            // --------- Set up stream to decode the asn.1 encoded RSA private key ------
            MemoryStream mem = new MemoryStream(privkey);
            BinaryReader binr = new BinaryReader(mem);  //wrap Memory Stream with BinaryReader for easy reading
            byte bt = 0;
            ushort twobytes = 0;
            int elems = 0;
            try
            {
                twobytes = binr.ReadUInt16();
                if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
                    binr.ReadByte();    //advance 1 byte
                else if (twobytes == 0x8230)
                    binr.ReadInt16();    //advance 2 bytes
                else
                    return null;

                twobytes = binr.ReadUInt16();
                if (twobytes != 0x0102) //version number
                    return null;
                bt = binr.ReadByte();
                if (bt != 0x00)
                    return null;


                //------ all private key components are Integer sequences ----
                elems = GetIntegerSize(binr);
                MODULUS = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                E = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                D = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                P = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                Q = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                DP = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                DQ = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                IQ = binr.ReadBytes(elems);


                // ------- create RSACryptoServiceProvider instance and initialize with public key -----
                CspParameters CspParameters = new CspParameters();
                CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;

                int bitLen = 1024;
                if ("RSA2".Equals(signType))
                {
                    bitLen = 2048;
                }

                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(bitLen, CspParameters);
                RSAParameters RSAparams = new RSAParameters();
                RSAparams.Modulus = MODULUS;
                RSAparams.Exponent = E;
                RSAparams.D = D;
                RSAparams.P = P;
                RSAparams.Q = Q;
                RSAparams.DP = DP;
                RSAparams.DQ = DQ;
                RSAparams.InverseQ = IQ;
                RSA.ImportParameters(RSAparams);
                return RSA;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                binr.Close();
            }
        }

        private static int GetIntegerSize(BinaryReader binr)
        {
            byte bt = 0;
            byte lowbyte = 0x00;
            byte highbyte = 0x00;
            int count = 0;
            bt = binr.ReadByte();
            if (bt != 0x02)		//expect integer
                return 0;
            bt = binr.ReadByte();

            if (bt == 0x81)
                count = binr.ReadByte();	// data size in next byte
            else
                if (bt == 0x82)
            {
                highbyte = binr.ReadByte(); // data size in next 2 bytes
                lowbyte = binr.ReadByte();
                byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
                count = BitConverter.ToInt32(modint, 0);
            }
            else
            {
                count = bt;     // we already have the data size
            }

            while (binr.ReadByte() == 0x00)
            {	//remove high order zeros in data
                count -= 1;
            }
            binr.BaseStream.Seek(-1, SeekOrigin.Current);		//last ReadByte wasn't a removed zero, so back up a byte
            return count;
        }

    }
}